﻿using markdown_picture_packer.backend;
using markdown_picture_packer.common.constants;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;

namespace markdown_picture_packer.common.utils
{
    public class FileUtil
    {
        //验证文件
        public static Result ValidateFile(string filePath)
        {
            // 1. 检查文件路径是否为null或空
            if (string.IsNullOrEmpty(filePath)) return Result.Fail(FileValidationMessage.FILE_PATH_EMPTY);
            try
            {
                // 2. 验证路径格式是否合法
                if (!Path.IsPathRooted(filePath)) return Result.Fail(FileValidationMessage.INVALID_PATH_FORMAT);
                // 3. 检查路径中是否包含非法字符
                char[] invalidChars = Path.GetInvalidPathChars();
                if (filePath.IndexOfAny(invalidChars) >= 0) return Result.Fail(FileValidationMessage.INVALID_PATH_CHARS);
                // 4. 验证文件是否存在
                if (!File.Exists(filePath)) return Result.Fail(FileValidationMessage.FILE_NOT_FOUND);
                // 5. 检查文件权限（需要适当的权限才能执行）
                try
                {
                    FileSecurity fileSecurity = File.GetAccessControl(filePath);
                    AuthorizationRuleCollection rules = fileSecurity.GetAccessRules(true, true, typeof(NTAccount));
                    // 检查当前用户是否有读取权限
                    WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent();
                    WindowsPrincipal currentPrincipal = new WindowsPrincipal(currentIdentity);
                    bool hasReadPermission = false;
                    foreach (FileSystemAccessRule rule in rules)
                    {
                        if (currentPrincipal.IsInRole(rule.IdentityReference.Value))
                        {
                            if ((rule.FileSystemRights & FileSystemRights.ReadData) == FileSystemRights.ReadData ||
                                (rule.FileSystemRights & FileSystemRights.Read) == FileSystemRights.Read)
                            {
                                if (rule.AccessControlType == AccessControlType.Allow) hasReadPermission = true;
                                else if (rule.AccessControlType == AccessControlType.Deny) hasReadPermission = false;
                            }
                        }
                    }
                    if (!hasReadPermission) return Result.Fail(FileValidationMessage.READ_PERMISSION_DENIED);
                }
                catch (UnauthorizedAccessException)
                {
                    return Result.Fail(FileValidationMessage.SECURITY_CHECK_ACCESS_DENIED);
                }
                // 6. 检查文件是否被锁定或正在使用
                try
                {
                    using (FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { }// 文件可访问，立即关闭流
                }
                catch (IOException)
                {
                    return Result.Fail(FileValidationMessage.FILE_LOCKED);
                }
                return Result.Success(FileValidationMessage.SUCCESS); // 所有校验通过
            }
            catch (Exception ex)
            {
                return Result.Fail($"{FileValidationMessage.GENERIC_EXCEPTION}{ex.Message}");
            }
        }
        // 异步下载图片方法
        public static async Task<Result> DownloadImageAsync(string url, string localFolderPath, string saveName)
        {
            HttpClient httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(6) };
            try
            {
                // 验证参数
                if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(localFolderPath) || string.IsNullOrEmpty(saveName))
                {
                    return Result.Fail(DownloadMessage.URL_LOCAL_DIR_OR_SAVE_NAME_CANNOT_BE_EMPTY);
                }
                // 确保目录存在
                if (!Directory.Exists(localFolderPath)) Directory.CreateDirectory(localFolderPath);
                // 发送HTTP请求并获取响应
                using (var response = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
                {
                    response.EnsureSuccessStatusCode();
                    // 获取内容类型
                    string contentType = response.Content.Headers.ContentType?.MediaType?.ToLowerInvariant() ?? string.Empty;
                    string fileExtension = GetExtensionFromContentType(contentType);
                    if (string.IsNullOrEmpty(fileExtension))
                    {
                        return Result.Fail($"{DownloadMessage.UNSUPPORTED_CONTENT_TYPE}:{contentType}");
                    }
                    // 构建完整文件路径
                    string filePath = Path.Combine(localFolderPath, $"{saveName}{fileExtension}");
                    // 异步保存文件
                    using (var stream = await response.Content.ReadAsStreamAsync())
                    using (FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true))
                    {
                        await stream.CopyToAsync(fileStream);
                    }

                    return Result.Success(filePath);
                }
            }
            catch (TaskCanceledException ex)
            {
                if (ex.CancellationToken.IsCancellationRequested)
                {
                    return Result.Fail(DownloadMessage.OPERATION_CANCELED);
                }
                else
                {
                    return Result.Fail(DownloadMessage.DOWNLOAD_TIMEOUT);
                }
            }
            catch (HttpRequestException)
            {
                return Result.Fail(DownloadMessage.NETWORK_ERROR);
            }
            catch (UriFormatException)
            {
                return Result.Fail(DownloadMessage.INVALID_URL_FORMAT);
            }
            catch (DirectoryNotFoundException)
            {
                return Result.Fail(DownloadMessage.DIRECTORY_NOT_FOUND);
            }
            catch (UnauthorizedAccessException)
            {
                return Result.Fail(DownloadMessage.UNAUTHORIZED_ACCESS);
            }
            catch (IOException)
            {
                return Result.Fail(DownloadMessage.FILE_OPERATION_ERROR);
            }
            catch (NotSupportedException)
            {
                return Result.Fail(DownloadMessage.UNSUPPORTED_URL_FORMAT);
            }
            catch (Exception)
            {
                return Result.Fail(DownloadMessage.UNKNOWN_ERROR);
            }
        }
        private static string GetExtensionFromContentType(string contentType)
        {
            return Constants.MIME_TYPE_EXTENSIONS.TryGetValue(contentType.Split(';')[0].Trim(), out var extension) ? extension : null;
        }
        // 异步写入多行文本到文件
        public static async Task WriteAllLinesAsync(string filePath, string[] lines,
            Encoding encoding = null, bool append = false)
        {
            encoding = encoding ?? Encoding.UTF8;
            using (var fileStream = new FileStream(
                filePath,
                append ? FileMode.Append : FileMode.Create,
                FileAccess.Write,
                FileShare.None,
                bufferSize: 4096,
                useAsync: true))
            {
                using (var writer = new StreamWriter(fileStream, encoding))
                {
                    foreach (var line in lines)
                    {
                        await writer.WriteLineAsync(line);
                    }
                }
            }
        }

        public async static Task AsyncCopy(string sourcePath, string destinationPath)
        {
            using (var sourceStream = new FileStream(
                sourcePath,
                FileMode.Open,
                FileAccess.Read,
                FileShare.Read,
                bufferSize: 81920, // 80KB缓冲区（可根据文件大小调整）
                useAsync: true
            ))
            {
                using (var destinationStream = new FileStream(
                    destinationPath,
                    FileMode.Create,
                    FileAccess.Write,
                    FileShare.None,
                    bufferSize: 81920,
                    useAsync: true
                ))
                {
                    await sourceStream.CopyToAsync(destinationStream);
                }
            }
        }

    }
}
